package br.edu.ufcg.unknown.sintatico;

import java.io.File;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import br.edu.ufcg.unknown.exception.AnalisadorSemanticoUnknownRuntimeException;
import br.edu.ufcg.unknown.exception.AnalisadorSintaticoUnknownRuntimeException;
import br.edu.ufcg.unknown.exception.UnknownException;
import br.edu.ufcg.unknown.exception.UnknownRuntimeException;
import br.edu.ufcg.unknown.geradorDeCodigo.GeradorDeCodigo;
import br.edu.ufcg.unknown.lexico.AnalisadorLexico;
import br.edu.ufcg.unknown.lexico.Token;
import br.edu.ufcg.unknown.lexico.UnknownTest;
import br.edu.ufcg.unknown.semantico.AnalisadorSemantico;
import br.edu.ufcg.unknown.semantico.Tipo;

public class AnalisadorSintaticoTest extends UnknownTest {

	private IdentificaTK ident = new IdentificaTK();
	private AnalisadorSintatico as1;
	private GeradorDeCodigo geradorDeCodigo;

	private File palavrasReservadas = new File("resources" + File.separator
			+ "palavras-reservadas.txt");

	private List<String> listaVazia = new ArrayList<String>();

	protected void setUp() throws Exception {
		super.setUp();
		listaVazia = new ArrayList<String>();
		geradorDeCodigo = GeradorDeCodigo.getInstance();

	}

	protected void tearDown() throws Exception {
		super.tearDown();
		geradorDeCodigo.resetCodigos();
		geradorDeCodigo.resetTemp();
		geradorDeCodigo.resetTriplaAtual();
		geradorDeCodigo.resetLabel();
		geradorDeCodigo.resetTabLabel();
	}

	public void testPrograma() throws UnknownException {

		as1 = new AnalisadorSintatico("PROGRAM ident1 BEGIN END", palavrasReservadas);
		assertTrue(as1.programa());
		as1 = new AnalisadorSintatico("PROGRAM ident1 CONST DEZ = 10; BEGIN END",
				palavrasReservadas);
		assertTrue(as1.programa());
		as1 = new AnalisadorSintatico(
				"PROGRAM ident1 CONST DEZ = 10; VAR idade : INTEGER; BEGIN END", palavrasReservadas);
		assertTrue(as1.programa());
		as1 = new AnalisadorSintatico(
				"PROGRAM ident1 CONST DEZ = 10; VAR idade : INTEGER; SUBPROGRAMS SUBPROGRAM getIdade(); BEGIN WRITE('Calcular a Idade'); END; BEGIN END",
				palavrasReservadas);
		assertTrue(as1.programa());

	}

	public void testProgramaLancarErro() throws UnknownException {

		// 1o. Teste
		as1 = new AnalisadorSintatico("'cadeia'", palavrasReservadas);
		try {
			assertFalse(as1.programa());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		AnalisadorSintaticoUnknownRuntimeException exp = null;

		// 2o. Teste
		as1 = new AnalisadorSintatico("PROGRAM 'cadeia'", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("'cadeia'");
		exp.addLexemaEsperado(Token.TIPO_T_IDENT);
		try {
			as1.programa();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 3o. Teste
		as1 = new AnalisadorSintatico("PROGRAM ident1 'cadeia'", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("'cadeia'");
		exp.addLexemaEsperado("BEGIN");
		try {
			as1.programa();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

	}

	public void testValorTipo() throws UnknownException {
		as1 = new AnalisadorSintatico("INTEGER", palavrasReservadas);
		assertTrue(as1.valorTipo());
		as1 = new AnalisadorSintatico("BOOLEAN", palavrasReservadas);
		assertTrue(as1.valorTipo());
		as1 = new AnalisadorSintatico("STRING", palavrasReservadas);
		assertTrue(as1.valorTipo());
	}

	public void testValorTipoLancarErro() throws UnknownException {

		// 1o. Teste
		as1 = new AnalisadorSintatico("ident1", palavrasReservadas);
		try {
			assertFalse(as1.valorTipo());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}
	}

	public void testTipo() throws UnknownException {
		as1 = new AnalisadorSintatico("INTEGER", palavrasReservadas);
		assertTrue(as1.tipo());
		as1 = new AnalisadorSintatico("BOOLEAN", palavrasReservadas);
		assertTrue(as1.tipo());
		as1 = new AnalisadorSintatico("STRING", palavrasReservadas);
		assertTrue(as1.tipo());
		as1 = new AnalisadorSintatico("ARRAY [ 2 ] OF INTEGER", palavrasReservadas);
		assertTrue(as1.tipo());
		as1 = new AnalisadorSintatico("ARRAY [ 2 ] OF BOOLEAN", palavrasReservadas);
		assertTrue(as1.tipo());
		as1 = new AnalisadorSintatico("ARRAY [ 2 ] OF STRING", palavrasReservadas);
		assertTrue(as1.tipo());
	}

	public void testTipoLancarErro() throws UnknownException {
		AnalisadorSintaticoUnknownRuntimeException exp = null;
		AnalisadorSemanticoUnknownRuntimeException expS = null;

		// 1o. Teste
		as1 = new AnalisadorSintatico("ARRAY ident1 2 ] OF INTEGER", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("ident1");
		exp.addLexemaEsperado("[");
		try {
			as1.tipo();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 2o. Teste
		as1 = new AnalisadorSintatico("ARRAY [ ident1 ] OF INTEGER", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("ident1");
		exp.addLexemaEsperado(Token.TIPO_T_NUMERO);
		try {
			as1.tipo();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 3o. Teste
		as1 = new AnalisadorSintatico("ARRAY [ 2 ident1 OF INTEGER", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("ident1");
		exp.addLexemaEsperado("]");
		try {
			as1.tipo();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 4o. Teste
		as1 = new AnalisadorSintatico("ARRAY [ 2 ] ident1 INTEGER", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("ident1");
		exp.addLexemaEsperado("OF");
		try {
			as1.tipo();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 5o. Teste
		as1 = new AnalisadorSintatico("ARRAY [ 2 ] OF ident1", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("ident1");
		exp.addLexemaEsperado("INTEGER");
		exp.addLexemaEsperado("BOOLEAN");
		exp.addLexemaEsperado("STRING");
		try {
			as1.tipo();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 6o. Teste
		as1 = new AnalisadorSintatico("WRITE", palavrasReservadas);
		try {
			assertFalse(as1.tipo());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}
		
		// 7o. Teste
		as1 = new AnalisadorSintatico("ARRAY [ 0 ] OF INTEGER", palavrasReservadas);
		expS = new AnalisadorSemanticoUnknownRuntimeException("Linha: 1 - Coluna: 9 - Tamanho de array inválido: " + 0);
		try {
			as1.tipo();
			fail("Erro! Era pra ter sido lancada uma exceção de erro semântico");
		} catch (AnalisadorSemanticoUnknownRuntimeException e) {
			assertEquals(expS.getMessage(), e.getMessage());
		}

	}

	public void testEscrita() throws UnknownException {
		as1 = new AnalisadorSintatico("ident1", palavrasReservadas);
		addAtributo(as1, "ident1");
		assertTrue(as1.escrita());
		as1 = new AnalisadorSintatico("'This is Sparta!!!!'", palavrasReservadas);
		assertTrue(as1.escrita());
		as1 = new AnalisadorSintatico("12345", palavrasReservadas);
		assertTrue(as1.escrita());
		as1 = new AnalisadorSintatico("", palavrasReservadas);
		assertTrue(as1.escrita());
	}

	public void testEscritaLancarErro() throws UnknownException {

		// 1o. Teste
		as1 = new AnalisadorSintatico("WRITE", palavrasReservadas);
		try {
			assertTrue(as1.escrita());// Aceita como produção vazia
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

	}

	public void testValorTipoConstante() throws UnknownException {
		as1 = new AnalisadorSintatico("TRUE", palavrasReservadas);
		assertTrue(as1.valorTipoConstante());
		as1 = new AnalisadorSintatico("FALSE", palavrasReservadas);
		assertTrue(as1.valorTipoConstante());
		as1 = new AnalisadorSintatico("'Silence!!! I'll kill you!! Achmed - The dead therrorist!'",
				palavrasReservadas);
		assertTrue(as1.valorTipoConstante());
		as1 = new AnalisadorSintatico("2", palavrasReservadas);
		assertTrue(as1.valorTipoConstante());
	}

	public void testValorTipoConstanteLancarErro() throws UnknownException {

		// 1o. Teste
		as1 = new AnalisadorSintatico("ident1", palavrasReservadas);
		try {
			as1.valorTipoConstante();
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

	}

	// TODO Levar estes testes pra quem faz o serviço de <chamada_metodo>
	// public void testChamadoMetodo() throws UnknownException {
	// as1 = new AnalisadorSintatico("()", palavrasReservadas);
	// assertTrue(as1.chamadaMetodo());
	// as1 = new AnalisadorSintatico("( )", palavrasReservadas);
	// assertTrue(as1.chamadaMetodo());
	// }
	//
	// public void testChamadoMetodoLancarErro() throws UnknownException {
	//
	// // 1o. Teste
	// as1 = new AnalisadorSintatico("WRITE", palavrasReservadas);
	// try {
	// assertFalse(as1.chamadaMetodo());
	// } catch (AnalisadorSintaticoUnknownRuntimeException e) {
	// fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema
	// inesperado");
	// }
	//
	// AnalisadorSintaticoUnknownRuntimeException exp = null;
	//
	// // 2o. Teste
	// as1 = new AnalisadorSintatico("( 2", palavrasReservadas);
	// exp = new AnalisadorSintaticoUnknownRuntimeException("2");
	// exp.addLexemaEsperado(")");
	// try {
	// as1.chamadaMetodo();
	// fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
	// } catch (AnalisadorSintaticoUnknownRuntimeException e) {
	// assertEquals(exp, e);
	// }
	// }

	public void testDeclaracaoConstante() throws UnknownException {
		as1 = new AnalisadorSintatico("ident1 = TRUE", palavrasReservadas);
		assertTrue(as1.declaracaoConstante());
		as1 = new AnalisadorSintatico("ident1 = FALSE", palavrasReservadas);
		assertTrue(as1.declaracaoConstante());
		as1 = new AnalisadorSintatico("ident1 = 2", palavrasReservadas);
		assertTrue(as1.declaracaoConstante());
		as1 = new AnalisadorSintatico("ident1 = 'Uma cadeia de caracteres'", palavrasReservadas);
		assertTrue(as1.declaracaoConstante());
	}

	public void testDeclaracaoConstanteLancarErro() throws UnknownException {
		AnalisadorSintaticoUnknownRuntimeException exp = null;

		// 1o. Teste
		as1 = new AnalisadorSintatico("12345 = TRUE", palavrasReservadas);
		try {
			assertFalse(as1.declaracaoConstante());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		// 2o. Teste
		as1 = new AnalisadorSintatico("ident1 12345 TRUE", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("12345");
		exp.addLexemaEsperado("=");
		try {
			as1.declaracaoConstante();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 3o. Teste
		as1 = new AnalisadorSintatico("ident1 = WRITE", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado("TRUE");
		exp.addLexemaEsperado("FALSE");
		exp.addLexemaEsperado(Token.TIPO_T_NUMERO);
		exp.addLexemaEsperado(Token.TIPO_T_CADEIA);
		try {
			as1.declaracaoConstante();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

	}

	public void testListaDeclaracaoConstante() throws UnknownException {
		as1 = new AnalisadorSintatico("", palavrasReservadas);
		assertTrue(as1.listaDeclaracaoConstante());
		as1 = new AnalisadorSintatico("ident1 = TRUE;", palavrasReservadas);
		assertTrue(as1.listaDeclaracaoConstante());
		as1 = new AnalisadorSintatico("ident1 = TRUE;ident2 = FALSE;", palavrasReservadas);
		assertTrue(as1.listaDeclaracaoConstante());
		as1 = new AnalisadorSintatico("ident1 = TRUE; ident2 = FALSE;", palavrasReservadas);
		assertTrue(as1.listaDeclaracaoConstante());
	}

	public void testListaDeclaracaoConstanteLancarErro() throws UnknownException {
		AnalisadorSintaticoUnknownRuntimeException exp = null;

		// 1o. Teste
		as1 = new AnalisadorSintatico("ident1 = TRUE ident1", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("ident1");
		exp.addLexemaEsperado(";");
		try {
			as1.listaDeclaracaoConstante();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 2o. Teste
		as1 = new AnalisadorSintatico("ident1 = TRUE; WRITE", palavrasReservadas);
		try {
			assertTrue(as1.listaDeclaracaoConstante());// Produção vazia
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

	}

	public void testSecaoDeclaracaoConstantes() throws UnknownException {
		as1 = new AnalisadorSintatico("", palavrasReservadas);
		assertTrue(as1.listaDeclaracaoConstante());
		as1 = new AnalisadorSintatico("CONST", palavrasReservadas);
		assertTrue(as1.listaDeclaracaoConstante());
		as1 = new AnalisadorSintatico("CONST ident1 = TRUE;", palavrasReservadas);
		assertTrue(as1.listaDeclaracaoConstante());
		as1 = new AnalisadorSintatico("CONST ident1 = TRUE;ident1 = FALSE;", palavrasReservadas);
		assertTrue(as1.listaDeclaracaoConstante());
	}

	public void testSecaoDeclaracaoConstantesLancarErro() throws UnknownException {

		// 1o. Teste
		as1 = new AnalisadorSintatico("", palavrasReservadas);
		try {
			assertTrue(as1.secaoDeclaracaoConstantes());// Produção vazia
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		// 2o. Teste
		as1 = new AnalisadorSintatico("CONST WRITE", palavrasReservadas);
		try {
			assertTrue(as1.secaoDeclaracaoConstantes());// Produção vazia
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

	}

	public void testDeclaracaoVariavel() throws UnknownException {
		as1 = new AnalisadorSintatico("ident1 : INTEGER", palavrasReservadas);
		assertTrue(as1.declaracaoVariavel());
		as1 = new AnalisadorSintatico("ident1 : BOOLEAN", palavrasReservadas);
		assertTrue(as1.declaracaoVariavel());
		as1 = new AnalisadorSintatico("ident1 : STRING", palavrasReservadas);
		assertTrue(as1.declaracaoVariavel());
		as1 = new AnalisadorSintatico("ident1 : ARRAY [ 2 ] OF INTEGER", palavrasReservadas);
		assertTrue(as1.declaracaoVariavel());
		as1 = new AnalisadorSintatico("ident1 : ARRAY [ 2 ] OF BOOLEAN", palavrasReservadas);
		assertTrue(as1.declaracaoVariavel());
		as1 = new AnalisadorSintatico("ident1 : ARRAY [ 2 ] OF STRING", palavrasReservadas);
		assertTrue(as1.declaracaoVariavel());
	}

	public void testDeclaracaoVariavelLancarErro() throws UnknownException {
		AnalisadorSintaticoUnknownRuntimeException exp = null;

		// 1o. Teste
		as1 = new AnalisadorSintatico("12345 : INTEGER", palavrasReservadas);
		try {
			assertFalse(as1.declaracaoVariavel());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		// 2o. Teste
		as1 = new AnalisadorSintatico("ident1 12345 INTEGER", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("12345");
		exp.addLexemaEsperado(":");
		try {
			as1.declaracaoVariavel();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 3o. Teste
		as1 = new AnalisadorSintatico("ident1 : WRITE", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado("INTEGER");
		exp.addLexemaEsperado("BOOLEAN");
		exp.addLexemaEsperado("STRING");
		exp.addLexemaEsperado("ARRAY");
		try {
			as1.declaracaoVariavel();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}
	}

	public void testListaDeclaracaoVariavel() throws UnknownException {
		as1 = new AnalisadorSintatico("", palavrasReservadas);
		assertTrue(as1.listaDeclaracaoVariavel());
		as1 = new AnalisadorSintatico("ident1 : INTEGER;", palavrasReservadas);
		assertTrue(as1.listaDeclaracaoVariavel());
		as1 = new AnalisadorSintatico("ident1 : INTEGER;ident2 : BOOLEAN;", palavrasReservadas);
		assertTrue(as1.listaDeclaracaoVariavel());
		as1 = new AnalisadorSintatico("ident1 : INTEGER; ident2 : BOOLEAN;", palavrasReservadas);
		assertTrue(as1.listaDeclaracaoVariavel());
	}

	public void testListaDeclaracaoVariavelLancarErro() throws UnknownException {
		AnalisadorSintaticoUnknownRuntimeException exp = null;

		// 1o. Teste
		as1 = new AnalisadorSintatico("ident1 : INTEGER ident1", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("ident1");
		exp.addLexemaEsperado(";");
		try {
			as1.listaDeclaracaoVariavel();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 2o. Teste
		as1 = new AnalisadorSintatico("ident1 : INTEGER; WRITE", palavrasReservadas);
		try {
			assertTrue(as1.listaDeclaracaoVariavel());// Produção vazia
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}
	}

	public void testSecaoDeclaracaoVariaveis() throws UnknownException {
		as1 = new AnalisadorSintatico("", palavrasReservadas);
		assertTrue(as1.listaDeclaracaoVariavel());
		as1 = new AnalisadorSintatico("VAR", palavrasReservadas);
		assertTrue(as1.listaDeclaracaoVariavel());
		as1 = new AnalisadorSintatico("VAR ident1 : INTEGER;", palavrasReservadas);
		assertTrue(as1.listaDeclaracaoVariavel());
		as1 = new AnalisadorSintatico("VAR ident1 : INTEGER;ident1 : BOOLEAN;", palavrasReservadas);
		assertTrue(as1.listaDeclaracaoVariavel());
		as1 = new AnalisadorSintatico("VAR ident1 : INTEGER; ident1 : BOOLEAN;", palavrasReservadas);
		assertTrue(as1.listaDeclaracaoVariavel());
	}

	public void testSecaoDeclaracaoVariaveisLancarErro() throws UnknownException {

		// 1o. Teste
		as1 = new AnalisadorSintatico("", palavrasReservadas);
		try {
			assertTrue(as1.secaoDeclaracaoVariaveis());// Produção vazia
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		// 2o. Teste
		as1 = new AnalisadorSintatico("VAR WRITE", palavrasReservadas);
		try {
			assertTrue(as1.secaoDeclaracaoVariaveis());// Produção vazia
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}
	}

	public void testSubprograma() throws UnknownException {

		as1 = new AnalisadorSintatico("SUBPROGRAM ident1 ( ); BEGIN END", palavrasReservadas);
		assertTrue(as1.subprograma());
		as1 = new AnalisadorSintatico("SUBPROGRAM ident1 ( ); BEGIN WRITE(''); END",
				palavrasReservadas);
		assertTrue(as1.subprograma());
	}

	public void testSubprogramaLancarErro() throws UnknownException {

		// 1o. Teste
		as1 = new AnalisadorSintatico("'cadeia'", palavrasReservadas);
		try {
			assertFalse(as1.subprograma());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		AnalisadorSintaticoUnknownRuntimeException exp = null;

		// 2o. Teste
		as1 = new AnalisadorSintatico("SUBPROGRAM 'cadeia'", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("'cadeia'");
		exp.addLexemaEsperado(Token.TIPO_T_IDENT);
		try {
			as1.subprograma();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 3o. Teste
		as1 = new AnalisadorSintatico("SUBPROGRAM ident1 'cadeia'", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("'cadeia'");
		exp.addLexemaEsperado("(");
		try {
			as1.subprograma();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 4o. Teste
		as1 = new AnalisadorSintatico("SUBPROGRAM ident1 ( 'cadeia'", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("'cadeia'");
		exp.addLexemaEsperado(")");
		try {
			as1.subprograma();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 5o. Teste
		as1 = new AnalisadorSintatico("SUBPROGRAM ident1 ( ) 'cadeia'", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("'cadeia'");
		exp.addLexemaEsperado(";");
		try {
			as1.subprograma();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 6o. Teste
		as1 = new AnalisadorSintatico("SUBPROGRAM ident1 ( ); 'cadeia'", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("'cadeia'");
		exp.addLexemaEsperado("BEGIN");
		try {
			as1.subprograma();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}
	}

	public void testListaSubprograma() throws UnknownException {

		as1 = new AnalisadorSintatico("", palavrasReservadas);
		assertTrue(as1.listaSubprograma());
		as1 = new AnalisadorSintatico("SUBPROGRAM ident1 ( ); BEGIN END;", palavrasReservadas);
		assertTrue(as1.listaSubprograma());
		as1 = new AnalisadorSintatico(
				"SUBPROGRAM ident1 ( ); BEGIN END;SUBPROGRAM ident2 ( ); BEGIN WRITE(''); END;",
				palavrasReservadas);
		assertTrue(as1.listaSubprograma());
		as1 = new AnalisadorSintatico(
				"SUBPROGRAM ident1 ( ); BEGIN END; SUBPROGRAM ident2 ( ); BEGIN WRITE(''); END;",
				palavrasReservadas);
		assertTrue(as1.listaSubprograma());
	}

	public void testListaSubprogramaLancarErro() throws UnknownException {

		AnalisadorSintaticoUnknownRuntimeException exp = null;

		// 1o. Teste
		as1 = new AnalisadorSintatico("SUBPROGRAM ident1 ( ); BEGIN END ident1", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("ident1");
		exp.addLexemaEsperado(";");
		try {
			as1.listaSubprograma();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 2o. Teste
		as1 = new AnalisadorSintatico("SUBPROGRAM ident1 ( ); BEGIN END; WRITE", palavrasReservadas);
		try {
			assertTrue(as1.listaSubprograma());// Produção vazia
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}
	}

	public void testSecaoSubprograma() throws UnknownException {

		as1 = new AnalisadorSintatico("", palavrasReservadas);
		assertTrue(as1.listaSubprograma());
		as1 = new AnalisadorSintatico("SUBPROGRAMS SUBPROGRAM ident1 ( ); BEGIN END;",
				palavrasReservadas);
		assertTrue(as1.listaSubprograma());
		as1 = new AnalisadorSintatico(
				"SUBPROGRAMS SUBPROGRAM ident1 ( ); BEGIN END;SUBPROGRAM ident1 ( ); BEGIN WRITE(''); END;",
				palavrasReservadas);
		assertTrue(as1.listaSubprograma());
		as1 = new AnalisadorSintatico(
				"SUBPROGRAMS SUBPROGRAM ident1 ( ); BEGIN END; SUBPROGRAM ident1 ( ); BEGIN WRITE(''); END;",
				palavrasReservadas);
		assertTrue(as1.listaSubprograma());
	}

	public void testSecaoSubprogramaLancarErro() throws UnknownException {

		// 1o. Teste
		as1 = new AnalisadorSintatico("", palavrasReservadas);
		try {
			assertTrue(as1.listaSubprograma());// Produção vazia
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		// 2o. Teste
		as1 = new AnalisadorSintatico("SUBPROGRAMS WRITE", palavrasReservadas);
		try {
			assertTrue(as1.listaSubprograma());// Produção vazia
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}
	}

	public void testExpressaoUnaria() throws UnknownException {
		as1 = new AnalisadorSintatico("ident1", palavrasReservadas);
		addAtributo(as1, "ident1");
		assertTrue(as1.expressaoUnaria(listaVazia));
		as1 = new AnalisadorSintatico("2", palavrasReservadas);
		assertTrue(as1.expressaoUnaria(listaVazia));
		as1 = new AnalisadorSintatico("TRUE", palavrasReservadas);
		assertTrue(as1.expressaoUnaria(listaVazia));
		as1 = new AnalisadorSintatico("FALSE", palavrasReservadas);
		assertTrue(as1.expressaoUnaria(listaVazia));
		as1 = new AnalisadorSintatico("NOT ident1", palavrasReservadas);
		addAtributo(as1, "ident1");
		assertTrue(as1.expressaoUnaria(listaVazia));
		as1 = new AnalisadorSintatico("NOT 2", palavrasReservadas);
		assertTrue(as1.expressaoUnaria(listaVazia));
		as1 = new AnalisadorSintatico("NOT TRUE", palavrasReservadas);
		assertTrue(as1.expressaoUnaria(listaVazia));
		as1 = new AnalisadorSintatico("NOT FALSE", palavrasReservadas);
		assertTrue(as1.expressaoUnaria(listaVazia));
		as1 = new AnalisadorSintatico("- ident1", palavrasReservadas);
		addAtributo(as1, "ident1");
		assertTrue(as1.expressaoUnaria(listaVazia));
		as1 = new AnalisadorSintatico("- 2", palavrasReservadas);
		assertTrue(as1.expressaoUnaria(listaVazia));
		as1 = new AnalisadorSintatico("- TRUE", palavrasReservadas);
		assertTrue(as1.expressaoUnaria(listaVazia));
		as1 = new AnalisadorSintatico("- FALSE", palavrasReservadas);
		assertTrue(as1.expressaoUnaria(listaVazia));

		as1 = new AnalisadorSintatico("(ident1)", palavrasReservadas);
		addAtributo(as1, "ident1");
		assertTrue(as1.expressaoUnaria(listaVazia));
		as1 = new AnalisadorSintatico("(2)", palavrasReservadas);
		assertTrue(as1.expressaoUnaria(listaVazia));
		as1 = new AnalisadorSintatico("(TRUE)", palavrasReservadas);
		assertTrue(as1.expressaoUnaria(listaVazia));
		as1 = new AnalisadorSintatico("(FALSE)", palavrasReservadas);
		assertTrue(as1.expressaoUnaria(listaVazia));
		as1 = new AnalisadorSintatico("'uma cadeia'", palavrasReservadas);
		assertTrue(as1.expressaoUnaria(listaVazia));
		as1 = new AnalisadorSintatico("( 2 + 3 * 2 / (5 - 3) )", palavrasReservadas);
		assertTrue(as1.expressaoUnaria(listaVazia));
		as1 = new AnalisadorSintatico("( (2 * (9 - 7)) - 1)", palavrasReservadas);
		assertTrue(as1.expressaoUnaria(listaVazia));
	}

	private void addAtributo(AnalisadorSintatico as1, String lexema) throws UnknownException {
		addAtributo(as1, lexema, null, false);
	}

	private void addAtributo(AnalisadorSintatico as1, String lexema, String tipo)
			throws UnknownException {
		addAtributo(as1, lexema, tipo, false);
	}

	private void addAtributo(AnalisadorSintatico as1, String lexema, String tipo, boolean ehArray)
			throws UnknownException {
		AnalisadorLexico al = null;
		Token tk = null;
		AnalisadorSemantico aSemantico = null;

		al = new AnalisadorLexico(lexema, this.palavrasReservadas);
		tk = al.getProxToken();
		aSemantico = as1.getASemantico();
		Tipo tipoI = new Tipo(tk);
		if (tipo != null) {
			tipoI.setTipo(tipo);
			if (ehArray) {
				tipoI.setEhArray(true);
			}
		}
		aSemantico.addSimbolo(tk, tipoI);
	}

	public void testExpressaoUnariaLancarErro() throws UnknownException {

		AnalisadorSintaticoUnknownRuntimeException exp = null;

		listaVazia = this.ident.getTokensDeSincronizacaoDeExpressaoUnaria();

		// Ler Token inválido e não achar token de sincronização
		as1 = new AnalisadorSintatico("WRITE", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertFalse(as1.expressaoUnaria(listaVazia));// Ñ achou token de
			// sincronização
			assertNull(as1.getTokenAtual());
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("WRITE WHILE", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertFalse(as1.expressaoUnaria(listaVazia));// Ñ achou token de
			// sincronização
			assertNull(as1.getTokenAtual());
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		// Ler Token inválido e achar token de sincronização

		as1 = new AnalisadorSintatico("WRITE ;", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertTrue(as1.expressaoUnaria(listaVazia));// Achou token de
			// sincronização
			assertEquals(as1.getTokenAtual().getLexema(), ";");
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("WRITE WHILE ;", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertTrue(as1.expressaoUnaria(listaVazia));// Achou token de
			// sincronização
			assertEquals(as1.getTokenAtual().getLexema(), ";");
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("NOT - NOT FALSE PROGRAM", palavrasReservadas);
		try {
			assertTrue(as1.expressaoUnaria(listaVazia));// Achou token de
			// sincronização
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertNull(as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("NOT - NOT BEGIN 2 PROGRAM", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("BEGIN");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertTrue(as1.expressaoUnaria(listaVazia));// Achou token de
			// sincronização
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("NOT - NOT WRITE TRUE", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertTrue(as1.expressaoUnaria(listaVazia));// Achou token de
			// sincronização
			assertNull(as1.getTokenAtual());
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("NOT - NOT NOT ;", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException(";");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertTrue(as1.expressaoUnaria(listaVazia));// Achou token de
			// sincronização
			assertEquals(as1.getTokenAtual().getLexema(), ";");
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("NOT - NOT WRITE NOT NOT - READLN NOT NOT TRUE",
				palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());

		AnalisadorSintaticoUnknownRuntimeException exp1 = new AnalisadorSintaticoUnknownRuntimeException(
				"READLN");
		exp1.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());

		exp.addErro(exp1);

		try {
			assertTrue(as1.expressaoUnaria(listaVazia));
			assertNull(as1.getTokenAtual());
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}
	}

	public void testExpressaoMultiplicativa() throws UnknownException {
		as1 = new AnalisadorSintatico("", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("* ident1", palavrasReservadas);
		addAtributo(as1, "ident1");
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("* 2", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("* TRUE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("* FALSE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("* NOT ident1", palavrasReservadas);
		addAtributo(as1, "ident1");
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("* NOT 2", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("* NOT TRUE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("* NOT FALSE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("* - ident1", palavrasReservadas);
		addAtributo(as1, "ident1");
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("* - 2", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("* - TRUE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("* - FALSE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("/ ident1", palavrasReservadas);
		addAtributo(as1, "ident1");
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("/ 2", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("/ TRUE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("/ FALSE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("/ NOT ident1", palavrasReservadas);
		addAtributo(as1, "ident1");
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("/ NOT 2", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("/ NOT TRUE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("/ NOT FALSE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("/ - ident1", palavrasReservadas);
		addAtributo(as1, "ident1");
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("/ - 2", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("/ - TRUE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("/ - FALSE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("DIV ident1", palavrasReservadas);
		addAtributo(as1, "ident1");
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("DIV 2", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("DIV TRUE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("DIV FALSE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("DIV NOT ident1", palavrasReservadas);
		addAtributo(as1, "ident1");
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("DIV NOT 2", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("DIV NOT TRUE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("DIV NOT FALSE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("DIV - ident1", palavrasReservadas);
		addAtributo(as1, "ident1");
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("DIV - 2", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("DIV - TRUE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("DIV - FALSE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("MOD ident1", palavrasReservadas);
		addAtributo(as1, "ident1");
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("MOD 2", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("MOD TRUE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("MOD FALSE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("MOD NOT ident1", palavrasReservadas);
		addAtributo(as1, "ident1");
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("MOD NOT 2", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("MOD NOT TRUE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("MOD NOT FALSE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("MOD - ident1", palavrasReservadas);
		addAtributo(as1, "ident1");
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("MOD - 2", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("MOD - TRUE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("MOD - FALSE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("AND ident1", palavrasReservadas);
		addAtributo(as1, "ident1");
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("AND 2", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("AND TRUE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("AND FALSE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("AND NOT ident1", palavrasReservadas);
		addAtributo(as1, "ident1");
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("AND NOT 2", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("AND NOT TRUE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("AND NOT FALSE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("AND - ident1", palavrasReservadas);
		addAtributo(as1, "ident1");
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("AND - 2", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("AND - TRUE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));
		as1 = new AnalisadorSintatico("AND - FALSE", palavrasReservadas);
		assertTrue(as1.expressaoMultiplicativa(listaVazia));

	}

	public void testExpressaoMultiplicativaLancarErro() throws UnknownException {

		AnalisadorSintaticoUnknownRuntimeException exp = null;

		listaVazia = this.ident.getTokensDeSincronizacaoDeExpressaoMultiplicativa();

		// Ler Token inválido e aceitar Produção Vazia
		as1 = new AnalisadorSintatico("WRITE", palavrasReservadas);
		try {
			assertTrue(as1.expressaoMultiplicativa(listaVazia));// Produção
			// Vazia
			assertEquals(as1.getTokenAtual().getLexema(), "WRITE");
			assertNull(as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("WRITE WHILE", palavrasReservadas);
		try {
			assertTrue(as1.expressaoMultiplicativa(listaVazia));// Produção
			// Vazia
			assertEquals(as1.getTokenAtual().getLexema(), "WRITE");
			assertNull(as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("PROGRAM", palavrasReservadas);
		try {
			assertTrue(as1.expressaoMultiplicativa(listaVazia));// Produção
			// Vazia
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertNull(as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("* NOT TRUE / 10 PROGRAM", palavrasReservadas);
		try {
			assertTrue(as1.expressaoMultiplicativa(listaVazia));// Produção
			// Vazia
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertNull(as1.getErro());

		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("* NOT TRUE WRITE / 10 PROGRAM", palavrasReservadas);
		try {
			assertTrue(as1.expressaoMultiplicativa(listaVazia));// Produção
			// Vazia
			assertEquals(as1.getTokenAtual().getLexema(), "WRITE");
			assertNull(as1.getErro());

		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("* NOT WRITE / 10 PROGRAM", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());

		try {
			assertTrue(as1.expressaoMultiplicativa(listaVazia));// Produção
			// Vazia
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertEquals(exp, as1.getErro());

		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("* NOT WRITE / WHILE DIV 10 PROGRAM", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());

		AnalisadorSintaticoUnknownRuntimeException exp1 = new AnalisadorSintaticoUnknownRuntimeException(
				"WHILE");
		exp1.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());

		exp.addErro(exp1);

		try {
			assertTrue(as1.expressaoMultiplicativa(listaVazia));// Produção
			// Vazia
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertEquals(exp, as1.getErro());

		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("* NOT / 10 PROGRAM", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("/");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertTrue(as1.expressaoMultiplicativa(listaVazia));// Produção
			// Vazia
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertEquals(exp, as1.getErro());

		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("* NOT ( 10 ) / 10 PROGRAM", palavrasReservadas);
		try {
			assertTrue(as1.expressaoMultiplicativa(listaVazia));// Produção
			// Vazia
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertNull(as1.getErro());

		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("* NOT ( 10 WRITE ) / 10 WRITE PROGRAM", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(")");

		try {
			assertTrue(as1.expressaoMultiplicativa(listaVazia));// Produção
			// Vazia
			assertEquals(as1.getTokenAtual().getLexema(), "WRITE");
			assertEquals(exp, as1.getErro());

		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("* NOT ( WRITE / TRUE ) / 10 PROGRAM", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());

		try {
			assertTrue(as1.expressaoMultiplicativa(listaVazia));// Produção
			// Vazia
			assertEquals(exp, as1.getErro());

		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

	}

	public void testTermo() throws UnknownException {
		as1 = new AnalisadorSintatico("22 * 22", palavrasReservadas);
		assertTrue(as1.termo(listaVazia));
		as1 = new AnalisadorSintatico("11 / 22", palavrasReservadas);
		assertTrue(as1.termo(listaVazia));
	}

	public void testTermoLancarErro() throws UnknownException {

		AnalisadorSintaticoUnknownRuntimeException exp = null;

		listaVazia = this.ident.getTokensDeSincronizacaoDeTermo();

		// Ler Token inválido e não achar token de sincronização
		as1 = new AnalisadorSintatico("WRITE", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertFalse(as1.termo(listaVazia));// Ñ achou token de
			// sincronização
			assertNull(as1.getTokenAtual());
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("WRITE WHILE", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertFalse(as1.termo(listaVazia));// Ñ achou token de
			// sincronização
			assertNull(as1.getTokenAtual());
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		// Ler Token inválido e achar token de sincronização

		as1 = new AnalisadorSintatico("WRITE ;", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertTrue(as1.termo(listaVazia));// Achou token de
			// sincronização
			assertEquals(as1.getTokenAtual().getLexema(), ";");
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("WRITE WHILE ;", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertTrue(as1.termo(listaVazia));// Achou token de
			// sincronização
			assertEquals(as1.getTokenAtual().getLexema(), ";");
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("NOT 10 WRITE DIV 10 PROGRAM", palavrasReservadas);
		try {
			assertTrue(as1.termo(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "WRITE"); // produção
			// vazia
			assertNull(as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("NOT (TRUE) AND FALSE PROGRAM", palavrasReservadas);
		try {
			assertTrue(as1.termo(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM"); // produção
			// vazia
			assertNull(as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("NOT ( WRITE TRUE ) AND FALSE PROGRAM", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertTrue(as1.termo(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM"); // produção
			// vazia
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("NOT ( TRUE WRITE ) AND FALSE PROGRAM", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(")");
		try {
			assertTrue(as1.termo(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM"); // produção
			// vazia
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("10 * WRITE AND FALSE PROGRAM", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertTrue(as1.termo(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM"); // produção
			// vazia
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

	}

	public void testExpressaoAditiva() throws UnknownException {
		as1 = new AnalisadorSintatico("+ 11 / 22", palavrasReservadas);
		assertTrue(as1.expressaoAditiva(listaVazia));
		as1 = new AnalisadorSintatico("", palavrasReservadas);
		assertTrue(as1.expressaoAditiva(listaVazia));

		as1 = new AnalisadorSintatico("+ 1", palavrasReservadas);
		assertTrue(as1.expressaoAditiva(listaVazia));
		as1 = new AnalisadorSintatico("OR FALSE", palavrasReservadas);
		assertTrue(as1.expressaoAditiva(listaVazia));
		as1 = new AnalisadorSintatico("- 2", palavrasReservadas);
		assertTrue(as1.expressaoAditiva(listaVazia));

	}

	public void testExpressaoAditivaLancarErro() throws UnknownException {

		AnalisadorSintaticoUnknownRuntimeException exp = null;

		listaVazia = this.ident.getTokensDeSincronizacaoDeExpressaoAditiva();

		// Ler Token inválido e aceitar Produção Vazia
		as1 = new AnalisadorSintatico("WRITE", palavrasReservadas);
		try {
			assertTrue(as1.expressaoAditiva(listaVazia));// Produção
			// Vazia
			assertEquals(as1.getTokenAtual().getLexema(), "WRITE");
			assertNull(as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("WRITE WHILE", palavrasReservadas);
		try {
			assertTrue(as1.expressaoAditiva(listaVazia));// Produção
			// Vazia
			assertEquals(as1.getTokenAtual().getLexema(), "WRITE");
			assertNull(as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("PROGRAM", palavrasReservadas);
		try {
			assertTrue(as1.expressaoAditiva(listaVazia));// Produção
			// Vazia
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertNull(as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("+ 10 * NOT WRITE / 10 PROGRAM", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());

		try {
			assertTrue(as1.expressaoAditiva(listaVazia));// Produção
			// Vazia
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertEquals(exp, as1.getErro());

		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("+ 10 * NOT WRITE / WHILE DIV 10 PROGRAM", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());

		AnalisadorSintaticoUnknownRuntimeException exp1 = new AnalisadorSintaticoUnknownRuntimeException(
				"WHILE");
		exp1.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());

		exp.addErro(exp1);

		try {
			assertTrue(as1.expressaoAditiva(listaVazia));// Produção
			// Vazia
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertEquals(exp, as1.getErro());

		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("+ 10 * NOT / 10 PROGRAM", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("/");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertTrue(as1.expressaoAditiva(listaVazia));// Produção
			// Vazia
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertEquals(exp, as1.getErro());

		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("+ 10 * NOT ( 10 ) / 10 PROGRAM", palavrasReservadas);
		try {
			assertTrue(as1.expressaoAditiva(listaVazia));// Produção
			// Vazia
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertNull(as1.getErro());

		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("+ 10 * NOT ( 10 WRITE ) / 10 WRITE PROGRAM",
				palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(")");

		try {
			assertTrue(as1.expressaoAditiva(listaVazia));// Produção
			// Vazia
			assertEquals(as1.getTokenAtual().getLexema(), "WRITE");
			assertEquals(exp, as1.getErro());

		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("+ 10 * NOT ( WRITE / TRUE ) / 10 PROGRAM",
				palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());

		try {
			assertTrue(as1.expressaoAditiva(listaVazia));// Produção
			// Vazia
			assertEquals(exp, as1.getErro());

		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

	}

	public void testExpressaoSimples() throws UnknownException {
		as1 = new AnalisadorSintatico("11 / 22 + 11 DIV 22", palavrasReservadas);
		assertTrue(as1.expressaoSimples(listaVazia));
		as1 = new AnalisadorSintatico("11 / 22 + 11 DIV 22", palavrasReservadas);
		assertTrue(as1.expressaoSimples(listaVazia));
		as1 = new AnalisadorSintatico("NOT TRUE OR FALSE", palavrasReservadas);
		assertTrue(as1.expressaoSimples(listaVazia));

	}

	public void testExpressaoSimplesLancarErro() throws UnknownException {

		AnalisadorSintaticoUnknownRuntimeException exp = null;

		listaVazia = this.ident.getTokensDeSincronizacaoDeExpressaoSimples();

		// Ler Token inválido e não achar token de sincronização
		as1 = new AnalisadorSintatico("WRITE", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertFalse(as1.expressaoSimples(listaVazia));// Ñ achou token de
			// sincronização
			assertNull(as1.getTokenAtual());
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("WRITE WHILE", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertFalse(as1.expressaoSimples(listaVazia));// Ñ achou token de
			// sincronização
			assertNull(as1.getTokenAtual());
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		// Ler Token inválido e achar token de sincronização

		as1 = new AnalisadorSintatico("WRITE ;", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertTrue(as1.expressaoSimples(listaVazia));// Achou token de
			// sincronização
			assertEquals(as1.getTokenAtual().getLexema(), ";");
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("WRITE WHILE ;", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertTrue(as1.expressaoSimples(listaVazia));// Achou token de
			// sincronização
			assertEquals(as1.getTokenAtual().getLexema(), ";");
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		// inicio

		as1 = new AnalisadorSintatico("NOT 10 WRITE DIV 10 + 10 AND TRUE PROGRAM",
				palavrasReservadas);
		try {
			assertTrue(as1.expressaoSimples(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "WRITE"); // produção
			// vazia
			assertNull(as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("NOT (TRUE) AND FALSE  + 10 AND TRUE PROGRAM",
				palavrasReservadas);
		try {
			assertTrue(as1.expressaoSimples(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM"); // produção
			// vazia
			assertNull(as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("NOT ( WRITE TRUE ) AND FALSE  + 10 AND TRUE PROGRAM",
				palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertTrue(as1.expressaoSimples(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM"); // produção
			// vazia
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("NOT ( TRUE WRITE ) AND FALSE  + 10 AND TRUE PROGRAM",
				palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(")");
		try {
			assertTrue(as1.expressaoSimples(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM"); // produção
			// vazia
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("10 * WRITE AND FALSE + 10 AND TRUE PROGRAM",
				palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertTrue(as1.expressaoSimples(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM"); // produção
			// vazia
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

	}

	public void testExpressaoRelacional() throws UnknownException {
		as1 = new AnalisadorSintatico("= 11 / 22 + 11 DIV 22", palavrasReservadas);
		assertTrue(as1.expressaoRelacional(listaVazia));
		as1 = new AnalisadorSintatico(">= 22 / 22 + 11 DIV 22", palavrasReservadas);
		assertTrue(as1.expressaoRelacional(listaVazia));
		as1 = new AnalisadorSintatico("<> NOT TRUE OR FALSE", palavrasReservadas);
		assertTrue(as1.expressaoRelacional(listaVazia));

		as1 = new AnalisadorSintatico("= 2", palavrasReservadas);
		assertTrue(as1.expressaoRelacional(listaVazia));
		as1 = new AnalisadorSintatico("<> 2", palavrasReservadas);
		assertTrue(as1.expressaoRelacional(listaVazia));
		as1 = new AnalisadorSintatico("> 2", palavrasReservadas);
		assertTrue(as1.expressaoRelacional(listaVazia));
		as1 = new AnalisadorSintatico("< 2", palavrasReservadas);
		assertTrue(as1.expressaoRelacional(listaVazia));
		as1 = new AnalisadorSintatico(">= 2", palavrasReservadas);
		assertTrue(as1.expressaoRelacional(listaVazia));
		as1 = new AnalisadorSintatico("<= 2", palavrasReservadas);
		assertTrue(as1.expressaoRelacional(listaVazia));

	}

	public void testExpressaoRelacionalLancarErro() throws UnknownException {

		AnalisadorSintaticoUnknownRuntimeException exp = null;

		listaVazia = this.ident.getTokensDeSincronizacaoDeExpressaoRelacional();

		// Ler Token inválido e aceitar Produção Vazia
		as1 = new AnalisadorSintatico("WRITE", palavrasReservadas);
		try {
			assertTrue(as1.expressaoRelacional(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "WRITE");
			assertNull(as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("WRITE WHILE", palavrasReservadas);
		try {
			assertTrue(as1.expressaoRelacional(listaVazia));// Produção
			// Vazia
			assertEquals(as1.getTokenAtual().getLexema(), "WRITE");
			assertNull(as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("PROGRAM", palavrasReservadas);
		try {
			assertTrue(as1.expressaoRelacional(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertNull(as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		// inicio

		as1 = new AnalisadorSintatico("= TRUE MOD 10 + 10 * NOT WRITE / 10 PROGRAM",
				palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());

		try {
			assertTrue(as1.expressaoRelacional(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertEquals(exp, as1.getErro());

		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("= TRUE MOD 10 + 10 * NOT WRITE / WHILE DIV 10 PROGRAM",
				palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());

		AnalisadorSintaticoUnknownRuntimeException exp1 = new AnalisadorSintaticoUnknownRuntimeException(
				"WHILE");
		exp1.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());

		exp.addErro(exp1);

		try {
			assertTrue(as1.expressaoRelacional(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertEquals(exp, as1.getErro());

		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("= TRUE MOD 10 + 10 * NOT / 10 PROGRAM", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("/");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertTrue(as1.expressaoRelacional(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertEquals(exp, as1.getErro());

		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("= TRUE MOD 10 + 10 * NOT ( 10 ) / 10 PROGRAM",
				palavrasReservadas);
		try {
			assertTrue(as1.expressaoRelacional(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertNull(as1.getErro());

		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("= TRUE MOD 10 + 10 * NOT ( 10 WRITE ) / 10 WRITE PROGRAM",
				palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(")");

		try {
			assertTrue(as1.expressaoRelacional(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "WRITE");
			assertEquals(exp, as1.getErro());

		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("= TRUE MOD 10 + 10 * NOT ( WRITE / TRUE ) / 10 PROGRAM",
				palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());

		try {
			assertTrue(as1.expressaoRelacional(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), ")");
			assertEquals(exp, as1.getErro());

		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

	}

	public void testExpressao() throws UnknownException {
		as1 = new AnalisadorSintatico("11 / 22 + 11 DIV 22 = 11 / 22 + 11 DIV 22",
				palavrasReservadas);
		assertTrue(as1.expressao(listaVazia));
		as1 = new AnalisadorSintatico("11 / 22 + 11 DIV 22 >= 22 / 22 + 11 DIV 22",
				palavrasReservadas);
		assertTrue(as1.expressao(listaVazia));
		as1 = new AnalisadorSintatico("NOT TRUE OR FALSE <> NOT TRUE OR FALSE", palavrasReservadas);
		assertTrue(as1.expressao(listaVazia));
		as1 = new AnalisadorSintatico("2 + 3 * 2 / (5 - 3) > (2 * (9 - 7)) - 1", palavrasReservadas);
		assertTrue(as1.expressao(listaVazia));
		as1 = new AnalisadorSintatico("( 2 + 3 * 2 / (5 - 3) > (2 * (9 - 7)) - 1 )",
				palavrasReservadas);
		assertTrue(as1.expressao(listaVazia));
		as1 = new AnalisadorSintatico("(( 2 + 3 * 2 / (5 - 3) > (2 * (9 - 7)) - 1 ) = TRUE )",
				palavrasReservadas);
		assertTrue(as1.expressao(listaVazia));
		as1 = new AnalisadorSintatico("(((( 2 + 3 * 2 / (5 - 3) > (2 * (9 - 7)) - 1 ) = TRUE )))",
				palavrasReservadas);
		assertTrue(as1.expressao(listaVazia));
		// Observe que o caso abaixo é semanticamente errado. Lembramos que
		// estamos no Analisador Sintático e este caso será tratado pelo
		// Analisador Semantico: ((a < b) > c)
		as1 = new AnalisadorSintatico("(( 2 + 3 * 2 / (5 - 3) > (2 * (9 - 7)) - 1 ))",
				palavrasReservadas);
		assertTrue(as1.expressao(listaVazia));
	}

	public void testExpressaoLancarErro() throws UnknownException {

		AnalisadorSintaticoUnknownRuntimeException exp = null;

		listaVazia = this.ident.getTokensDeSincronizacaoDeExpressao();

		// Ler Token inválido e não achar token de sincronização
		as1 = new AnalisadorSintatico("WRITE", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertFalse(as1.expressao(listaVazia));// Ñ achou token de
			// sincronização
			assertNull(as1.getTokenAtual());
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("WRITE WHILE", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertFalse(as1.expressao(listaVazia));// Ñ achou token de
			// sincronização
			assertNull(as1.getTokenAtual());
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		// Ler Token inválido e achar token de sincronização

		as1 = new AnalisadorSintatico("WRITE ;", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertTrue(as1.expressao(listaVazia));// Achou token de
			// sincronização
			assertEquals(as1.getTokenAtual().getLexema(), ";");
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico("WRITE WHILE ;", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertTrue(as1.expressao(listaVazia));// Achou token de
			// sincronização
			assertEquals(as1.getTokenAtual().getLexema(), ";");
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		// inicio

		as1 = new AnalisadorSintatico(
				"10 * 20 + ; TRUE = TRUE MOD 10 + 10 * NOT 10 WRITE DIV 10 + 10 AND TRUE PROGRAM",
				palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException(";");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertTrue(as1.expressao(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), ";");
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico(
				"10 * 20 + TRUE = TRUE MOD 10 + 10 * NOT 10 WRITE DIV 10 + 10 AND TRUE PROGRAM",
				palavrasReservadas);
		try {
			assertTrue(as1.expressao(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "WRITE");
			assertNull(as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico(
				"10 * 20 + TRUE = TRUE MOD 10 + 10 * NOT (TRUE) AND FALSE  + 10 AND TRUE PROGRAM",
				palavrasReservadas);
		try {
			assertTrue(as1.expressao(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertNull(as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico(
				"10 * 20 + TRUE = TRUE MOD 10 + 10 * NOT ( WRITE TRUE ) AND FALSE  + 10 AND TRUE PROGRAM",
				palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertTrue(as1.expressao(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico(
				"10 * 20 + TRUE = TRUE MOD 10 + 10 * NOT ( TRUE WRITE ) AND FALSE  + 10 AND TRUE PROGRAM",
				palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(")");
		try {
			assertTrue(as1.expressao(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		as1 = new AnalisadorSintatico(
				"10 * 20 + TRUE = TRUE MOD 10 + 10 * 10 * WRITE AND FALSE + 10 AND TRUE PROGRAM",
				palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(this.ident.getPrimeirosDeExpressaoUnaria());
		try {
			assertTrue(as1.expressao(listaVazia));
			assertEquals(as1.getTokenAtual().getLexema(), "PROGRAM");
			assertEquals(exp, as1.getErro());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

	}

	public void testComandoIdentificador() throws UnknownException {
		as1 = new AnalisadorSintatico(":= 11 / 22 + 11 DIV 22 = 11 / 22 + 11 DIV 22",
				palavrasReservadas);
		assertTrue(as1.comandoIdentificador());
		as1 = new AnalisadorSintatico(":= 11 / 22 + 11 DIV 22 >= 22 / 22 + 11 DIV 22",
				palavrasReservadas);
		assertTrue(as1.comandoIdentificador());
		as1 = new AnalisadorSintatico(":= NOT TRUE OR FALSE <> NOT TRUE OR FALSE",
				palavrasReservadas);
		assertTrue(as1.comandoIdentificador());
		as1 = new AnalisadorSintatico("( )", palavrasReservadas);
		assertTrue(as1.comandoIdentificador());
	}

	public void testComandoIdentificadorLancarErro() throws UnknownException {

		// 1o. Teste
		as1 = new AnalisadorSintatico("'cadeia'", palavrasReservadas);
		try {
			assertFalse(as1.comandoIdentificador());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		// AnalisadorSintaticoUnknownRuntimeException exp = null;
		//
		// XXX Isso que estava sendo testado abaixo diz respeito a <expressão> e
		// não a <comando_identificador>
		// // 2o. Teste
		// as1 = new AnalisadorSintatico(":= WRITE", palavrasReservadas);
		// exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		// exp.addLexemaEsperado("NOT");
		// exp.addLexemaEsperado("-");
		// exp.addLexemaEsperado("(");
		// exp.addLexemaEsperado(Token.TIPO_T_IDENT);
		// exp.addLexemaEsperado(Token.TIPO_T_NUMERO);
		// exp.addLexemaEsperado("TRUE");
		// exp.addLexemaEsperado("FALSE");
		// exp.addLexemaEsperado(Token.TIPO_T_CADEIA);
		// try {
		// as1.comandoIdentificador();
		// fail("Erro! Era pra ter sido lancada uma exceção de lexema
		// inesperado");
		// } catch (AnalisadorSintaticoUnknownRuntimeException e) {
		// assertEquals(exp, e);
		// }
	}

	public void testComandos() throws UnknownException {
		as1 = new AnalisadorSintatico("WRITE ( abcdef );", palavrasReservadas);
		addAtributo(as1, "abcdef");
		assertTrue(as1.comandos());
		as1 = new AnalisadorSintatico("WRITE (' abcdef '); READLN ( abcdef );", palavrasReservadas);
		addAtributo(as1, "abcdef");
		assertTrue(as1.comandos());
		as1 = new AnalisadorSintatico("abcdef:=11 / 22 + 11 DIV 22 = 11 / 22 + 11 DIV 22;",
				palavrasReservadas);
		addAtributo(as1, "abcdef", Tipo.T_BOOLEANO);
		assertTrue(as1.comandos());
	}

	public void testComandosLancarErro() throws UnknownException {

		// 1o. Teste
		as1 = new AnalisadorSintatico("'uma cadeia'", palavrasReservadas);
		try {
			assertTrue(as1.comandos());// Produção Vazia
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		AnalisadorSintaticoUnknownRuntimeException exp = null;

		// 2o. Teste
		as1 = new AnalisadorSintatico("WRITE('') 'cadeia'", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("'cadeia'");
		exp.addLexemaEsperado(";");
		try {
			as1.comandos();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 3o. Teste
		as1 = new AnalisadorSintatico("WRITE(''); 'cadeia'", palavrasReservadas);
		try {
			assertTrue(as1.comandos());// Produção Vazia
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

	}

	public void testComando() throws UnknownException {
		as1 = new AnalisadorSintatico("WRITE ( abcdef )", palavrasReservadas);
		addAtributo(as1, "abcdef");
		assertTrue(as1.comando());
		as1 = new AnalisadorSintatico("WRITE ( 12345 )", palavrasReservadas);
		assertTrue(as1.comando());
		as1 = new AnalisadorSintatico("READLN ( abcdef )", palavrasReservadas);
		addAtributo(as1, "abcdef");
		assertTrue(as1.comando());
		as1 = new AnalisadorSintatico("abcdef:=11 / 22 + 11 DIV 22 = 11 / 22 + 11 DIV 22",
				palavrasReservadas);
		addAtributo(as1, "abcdef", Tipo.T_BOOLEANO);
		assertTrue(as1.comando());
	}

	public void testComandoLancarErro() throws UnknownException {

		// 1o. Teste
		as1 = new AnalisadorSintatico("'uma cadeia'", palavrasReservadas);
		try {
			assertFalse(as1.comando());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		AnalisadorSintaticoUnknownRuntimeException exp = null;

		// 2o. Teste
		as1 = new AnalisadorSintatico("ident1 WRITE", palavrasReservadas);
		addAtributo(as1, "ident1");
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(":=");
		exp.addLexemaEsperado("(");
		exp.addLexemaEsperado("[");
		try {
			as1.comando();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 3o. Teste
		as1 = new AnalisadorSintatico("WRITE 'uma cadeia'", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("'uma cadeia'");
		exp.addLexemaEsperado("(");
		try {
			as1.comando();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 3o. Teste
		as1 = new AnalisadorSintatico("WRITE ( IF", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("IF");
		exp.addLexemaEsperado(")");
		exp.addLexemaEsperado(Token.TIPO_T_IDENT);
		exp.addLexemaEsperado(Token.TIPO_T_CADEIA);
		exp.addLexemaEsperado(Token.TIPO_T_NUMERO);
		try {
			as1.comando();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 4o. Teste
		as1 = new AnalisadorSintatico("READLN 'cadeia'", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("'cadeia'");
		exp.addLexemaEsperado("(");
		try {
			as1.comando();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 4o. Teste
		as1 = new AnalisadorSintatico("READLN ( 'cadeia'", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("'cadeia'");
		exp.addLexemaEsperado(Token.TIPO_T_IDENT);
		try {
			as1.comando();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 4o. Teste
		as1 = new AnalisadorSintatico("READLN ( ident1 'cadeia'", palavrasReservadas);
		addAtributo(as1, "ident1");
		exp = new AnalisadorSintaticoUnknownRuntimeException("'cadeia'");
		exp.addLexemaEsperado(")");
		try {
			as1.comando();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 5o. Teste
		as1 = new AnalisadorSintatico("IF 'cadeia'", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("'cadeia'");
		exp.addLexemaEsperado("(");
		try {
			as1.comando();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// XXX Isso que estava sendo testado abaixo diz respeito a <expressão> e
		// não a <comando>
		// // 6o. Teste
		// as1 = new AnalisadorSintatico("IF ( WRITE", palavrasReservadas);
		// exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		// exp.addLexemaEsperado("NOT");
		// exp.addLexemaEsperado("-");
		// exp.addLexemaEsperado("(");
		// exp.addLexemaEsperado(Token.TIPO_T_IDENT);
		// exp.addLexemaEsperado(Token.TIPO_T_NUMERO);
		// exp.addLexemaEsperado(Token.TIPO_T_CADEIA);
		// exp.addLexemaEsperado("TRUE");
		// exp.addLexemaEsperado("FALSE");
		// try {
		// as1.comando();
		// fail("Erro! Era pra ter sido lancada uma exceção de lexema
		// inesperado");
		// } catch (AnalisadorSintaticoUnknownRuntimeException e) {
		// assertEquals(exp, e);
		// }

		// 7o. Teste
		as1 = new AnalisadorSintatico("IF ( 2 > 1 WRITE", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(")");
		try {
			as1.comando();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 8o. Teste
		as1 = new AnalisadorSintatico("IF ( 2 > 1 ) WRITE", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado("THEN");
		try {
			as1.comando();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 9o. Teste
		as1 = new AnalisadorSintatico("IF ( 2 > 1 ) THEN WRITE", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado("BEGIN");
		try {
			as1.comando();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 10o. Teste
		as1 = new AnalisadorSintatico("IF ( 2 > 1 ) THEN BEGIN END", palavrasReservadas);
		try {
			assertTrue(as1.comando());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		// 11o. Teste
		as1 = new AnalisadorSintatico("IF ( 2 > 1 ) THEN BEGIN END ELSE BEGIN END",
				palavrasReservadas);
		try {
			assertTrue(as1.comando());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		// 12o. Teste
		as1 = new AnalisadorSintatico("WHILE 'cadeia'", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("'cadeia'");
		exp.addLexemaEsperado("(");
		try {
			as1.comando();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// XXX Isso que estava sendo testado abaixo diz respeito a <expressão> e
		// não a <comando>
		// // 13o. Teste
		// as1 = new AnalisadorSintatico("WHILE ( WRITE", palavrasReservadas);
		// exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		// exp.addLexemaEsperado("NOT");
		// exp.addLexemaEsperado("-");
		// exp.addLexemaEsperado("(");
		// exp.addLexemaEsperado(Token.TIPO_T_IDENT);
		// exp.addLexemaEsperado(Token.TIPO_T_NUMERO);
		// exp.addLexemaEsperado(Token.TIPO_T_CADEIA);
		// exp.addLexemaEsperado("TRUE");
		// exp.addLexemaEsperado("FALSE");
		// try {
		// as1.comando();
		// fail("Erro! Era pra ter sido lancada uma exceção de lexema
		// inesperado");
		// } catch (AnalisadorSintaticoUnknownRuntimeException e) {
		// assertEquals(exp, e);
		// }

		// 14o. Teste
		as1 = new AnalisadorSintatico("WHILE ( 2 < 3 WRITE", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado(")");
		try {
			as1.comando();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 15o. Teste
		as1 = new AnalisadorSintatico("WHILE ( 2 < 3 ) WRITE", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado("DO");
		try {
			as1.comando();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 16o. Teste
		as1 = new AnalisadorSintatico("WHILE ( 2 < 3 ) DO WRITE", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("WRITE");
		exp.addLexemaEsperado("BEGIN");
		try {
			as1.comando();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}
	}

	public void testComandoElse() throws UnknownException {
		as1 = new AnalisadorSintatico("", palavrasReservadas);
		assertTrue(as1.comandoElse());
		as1 = new AnalisadorSintatico("ELSE BEGIN END", palavrasReservadas);
		assertTrue(as1.comandoElse());
	}

	public void testComandoElseLancarErro() throws UnknownException {

		// 1o. Teste
		as1 = new AnalisadorSintatico("'cadeia'", palavrasReservadas);
		try {
			assertTrue(as1.comandoElse());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		AnalisadorSintaticoUnknownRuntimeException exp = null;

		// 2o. Teste
		as1 = new AnalisadorSintatico("ELSE 'cadeia'", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("'cadeia'");
		exp.addLexemaEsperado("BEGIN");
		try {
			as1.comandoElse();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}
	}

	public void testBloco() throws UnknownException {
		as1 = new AnalisadorSintatico("BEGIN WRITE (' abcdef '); READLN ( abcdef ); END;",
				palavrasReservadas);
		addAtributo(as1, "abcdef");
		assertTrue(as1.bloco());
		as1 = new AnalisadorSintatico("BEGIN WRITE (' abcdef '); READLN ( abcdef ); END;",
				palavrasReservadas);
		addAtributo(as1, "abcdef");
		assertTrue(as1.bloco());
		as1 = new AnalisadorSintatico(
				"BEGIN abcdef:=11 / 22 + 11 DIV 22 = 11 / 22 + 11 DIV 22; WRITE (' abcdef '); END;",
				palavrasReservadas);
		addAtributo(as1, "abcdef", Tipo.T_BOOLEANO);
		assertTrue(as1.bloco());
	}

	public void testBlocoLancarErro() throws UnknownException {

		AnalisadorSintaticoUnknownRuntimeException exp = null;

		// 1o. Teste
		as1 = new AnalisadorSintatico("'uma cadeia'", palavrasReservadas);
		try {
			assertFalse(as1.bloco());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}

		// 2o. Teste
		as1 = new AnalisadorSintatico("BEGIN WRITE(''); 'uma cadeia'", palavrasReservadas);
		exp = new AnalisadorSintaticoUnknownRuntimeException("'uma cadeia'");
		exp.addLexemaEsperado("END");
		try {
			as1.bloco();
			fail("Erro! Era pra ter sido lancada uma exceção de lexema inesperado");
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			assertEquals(exp, e);
		}

		// 3o. Teste
		as1 = new AnalisadorSintatico("BEGIN END", palavrasReservadas);
		try {
			assertTrue(as1.bloco());
		} catch (AnalisadorSintaticoUnknownRuntimeException e) {
			fail("Erro! NÃO era pra ter sido lancada uma exceção de lexema inesperado");
		}
	}

	// <Testes do IF>

	public void testIF1() throws UnknownException {

		as1 = new AnalisadorSintatico("IF ( 2 > 1 ) THEN BEGIN END", palavrasReservadas);

		as1.comando();

		List<String> codigosEsperado = new LinkedList<String>();
		codigosEsperado.add("1. t1 > 2 1");
		codigosEsperado.add("2. #4 jif");
		codigosEsperado.add("3. #4 jmp");
		List<String> codigosRecebido = GeradorDeCodigo.getInstance().getCodigos();

		assertEquals(codigosEsperado, codigosRecebido);
	}

	public void testIF2() throws UnknownException {

		as1 = new AnalisadorSintatico("IF ( 2 > 1 ) THEN BEGIN a := 2; END", palavrasReservadas);
		addAtributo(as1, "a", Tipo.T_INTEIRO);

		as1.comando();

		List<String> codigosEsperado = new LinkedList<String>();
		codigosEsperado.add("1. t1 > 2 1");
		codigosEsperado.add("2. #6 jif");
		codigosEsperado.add("3. t1 2");
		codigosEsperado.add("4. a := t1");
		codigosEsperado.add("5. #6 jmp");
		List<String> codigosRecebido = GeradorDeCodigo.getInstance().getCodigos();

		assertEquals(codigosEsperado, codigosRecebido);

	}

	public void testIF3() throws UnknownException {

		as1 = new AnalisadorSintatico("IF ( TRUE ) THEN BEGIN END", palavrasReservadas);

		as1.comando();

		List<String> codigosEsperado = new LinkedList<String>();
		codigosEsperado.add("1. t1 TRUE");
		codigosEsperado.add("2. #4 jif");
		codigosEsperado.add("3. #4 jmp");
		List<String> codigosRecebido = GeradorDeCodigo.getInstance().getCodigos();

		assertEquals(codigosEsperado, codigosRecebido);

	}

	public void testIF4() throws UnknownException {
		as1 = new AnalisadorSintatico("IF ( 2 > 1 ) THEN BEGIN END ELSE BEGIN END",
				palavrasReservadas);

		as1.comando();

		List<String> codigosEsperado = new LinkedList<String>();
		codigosEsperado.add("1. t1 > 2 1");
		codigosEsperado.add("2. #4 jif");
		codigosEsperado.add("3. #4 jmp");
		List<String> codigosRecebido = GeradorDeCodigo.getInstance().getCodigos();

		assertEquals(codigosEsperado, codigosRecebido);
	}

	public void testIF5() throws UnknownException {
		as1 = new AnalisadorSintatico("IF ( 2 > 1 ) THEN BEGIN a := 2; END ELSE BEGIN a := 3; END",
				palavrasReservadas);
		addAtributo(as1, "a", Tipo.T_INTEIRO);

		as1.comando();

		List<String> codigosEsperado = new LinkedList<String>();
		codigosEsperado.add("1. t1 > 2 1");
		codigosEsperado.add("2. #6 jif");
		codigosEsperado.add("3. t1 2");
		codigosEsperado.add("4. a := t1");
		codigosEsperado.add("5. #8 jmp");
		codigosEsperado.add("6. t1 3");
		codigosEsperado.add("7. a := t1");

		List<String> codigosRecebido = GeradorDeCodigo.getInstance().getCodigos();

		assertEquals(codigosEsperado, codigosRecebido);
	}

	public void testIF6() throws UnknownException {
		as1 = new AnalisadorSintatico("IF ( TRUE ) THEN BEGIN END ELSE BEGIN END",
				palavrasReservadas);

		as1.comando();

		List<String> codigosEsperado = new LinkedList<String>();
		codigosEsperado.add("1. t1 TRUE");
		codigosEsperado.add("2. #4 jif");
		codigosEsperado.add("3. #4 jmp");
		List<String> codigosRecebido = GeradorDeCodigo.getInstance().getCodigos();

		assertEquals(codigosEsperado, codigosRecebido);
	}

	public void testIF7() throws UnknownException {
		as1 = new AnalisadorSintatico("IF ( 2 > 1 ) THEN BEGIN a := 2; IF ( 2 > 1 )"
				+ " THEN BEGIN a := 7; END; END "
				+ "ELSE BEGIN a := 3; IF ( 2 > 1 ) THEN BEGIN a := 5; END; END", palavrasReservadas);
		addAtributo(as1, "a", Tipo.T_INTEIRO);

		as1.comando();

		List<String> codigosEsperado = new LinkedList<String>();
		codigosEsperado.add("1. t1 > 2 1");
		codigosEsperado.add("2. #11 jif");
		codigosEsperado.add("3. t1 2");
		codigosEsperado.add("4. a := t1");
		codigosEsperado.add("5. t2 > 2 1");
		codigosEsperado.add("6. #10 jif");
		codigosEsperado.add("7. t1 7");
		codigosEsperado.add("8. a := t1");
		codigosEsperado.add("9. #10 jmp");
		codigosEsperado.add("10. #18 jmp");
		codigosEsperado.add("11. t1 3");
		codigosEsperado.add("12. a := t1");
		codigosEsperado.add("13. t2 > 2 1");
		codigosEsperado.add("14. #18 jif");
		codigosEsperado.add("15. t1 5");
		codigosEsperado.add("16. a := t1");
		codigosEsperado.add("17. #18 jmp");

		List<String> codigosRecebido = GeradorDeCodigo.getInstance().getCodigos();

		assertEquals(codigosEsperado, codigosRecebido);
	}

	public void testIF8() throws UnknownException {
		as1 = new AnalisadorSintatico("IF ( 2 > 1 ) THEN "
				+ "BEGIN a := 2; WHILE (2 > 3) DO BEGIN B := TRUE; END; END "
				+ "ELSE BEGIN a := 3; END", palavrasReservadas);
		addAtributo(as1, "a", Tipo.T_INTEIRO);
		addAtributo(as1, "B", Tipo.T_BOOLEANO);

		as1.comando();

		List<String> codigosEsperado = new LinkedList<String>();
		codigosEsperado.add("1. t1 > 2 1");
		codigosEsperado.add("2. #11 jif");
		codigosEsperado.add("3. t1 2");
		codigosEsperado.add("4. a := t1");
		codigosEsperado.add("5. t2 > 2 3");
		codigosEsperado.add("6. #10 jif");
		codigosEsperado.add("7. t1 TRUE");
		codigosEsperado.add("8. B := t1");
		codigosEsperado.add("9. #5 jmp");
		codigosEsperado.add("10. #13 jmp");
		codigosEsperado.add("11. t1 3");
		codigosEsperado.add("12. a := t1");

		List<String> codigosRecebido = GeradorDeCodigo.getInstance().getCodigos();

		assertEquals(codigosEsperado, codigosRecebido);
	}

	// </Testes do IF>

	// <Testes da Atribuição>

	public void testAtribuicao1() throws UnknownException {
		as1 = new AnalisadorSintatico("A := 2", palavrasReservadas);

		addAtributo(as1, "A", Tipo.T_INTEIRO);

		List<String> strings = new LinkedList<String>();
		strings.add("1. t1 2");
		strings.add("2. A := t1");
		as1.comando();

		assertEquals(strings, geradorDeCodigo.getCodigos());
	}

	public void testAtribuicao2() throws UnknownException {
		as1 = new AnalisadorSintatico("A := 2 + 3 * 5 > 4 - 3 + 2 * 7", palavrasReservadas);

		addAtributo(as1, "A", Tipo.T_BOOLEANO);

		List<String> strings = new LinkedList<String>();
		strings.add("1. t1 * 3 5");
		strings.add("2. t2 + 2 t1");
		strings.add("3. t3 * 2 7");
		strings.add("4. t4 + 3 t3");
		strings.add("5. t5 - 4 t4");
		strings.add("6. t6 > t2 t5");
		strings.add("7. A := t6");
		as1.comando();

		assertEquals(strings, geradorDeCodigo.getCodigos());
	}

	public void testAtribuicao3() throws UnknownException {
		as1 = new AnalisadorSintatico("A := B AND TRUE OR FALSE", palavrasReservadas);

		addAtributo(as1, "A", Tipo.T_BOOLEANO);
		addAtributo(as1, "B", Tipo.T_BOOLEANO);
		List<String> strings = new LinkedList<String>();
		strings.add("1. t1 AND B TRUE");
		strings.add("2. t2 OR t1 FALSE");
		strings.add("3. A := t2");

		as1.comando();

		assertEquals(strings, geradorDeCodigo.getCodigos());
	}

	// </Testes da Atribuição>

	// <Testes do WHILE>

	public void testWhile1() throws UnknownException {
		as1 = new AnalisadorSintatico("WHILE (2 > 3) DO BEGIN A := TRUE; END", palavrasReservadas);

		addAtributo(as1, "A", Tipo.T_BOOLEANO);
		List<String> strings = new LinkedList<String>();
		strings.add("1. t1 > 2 3");
		strings.add("2. #6 jif");
		strings.add("3. t1 TRUE");
		strings.add("4. A := t1");
		strings.add("5. #1 jmp");

		as1.comando();

		assertEquals(strings, geradorDeCodigo.getCodigos());
	}

	public void testWhile2() throws UnknownException {
		as1 = new AnalisadorSintatico("WHILE (TRUE) DO BEGIN A := TRUE; END", palavrasReservadas);

		addAtributo(as1, "A", Tipo.T_BOOLEANO);
		List<String> strings = new LinkedList<String>();
		strings.add("1. t1 TRUE");
		strings.add("2. #6 jif");
		strings.add("3. t1 TRUE");
		strings.add("4. A := t1");
		strings.add("5. #1 jmp");

		as1.comando();

		assertEquals(strings, geradorDeCodigo.getCodigos());
	}

	public void testWhile3() throws UnknownException {
		as1 = new AnalisadorSintatico("WHILE (TRUE) DO BEGIN A := TRUE; WHILE (2 > 3) "
				+ "DO BEGIN A := FALSE; B := 2 + 3; END; END", palavrasReservadas);

		addAtributo(as1, "A", Tipo.T_BOOLEANO);
		addAtributo(as1, "B", Tipo.T_INTEIRO);
		List<String> strings = new LinkedList<String>();
		strings.add("1. t1 TRUE");
		strings.add("2. #13 jif");
		strings.add("3. t1 TRUE");
		strings.add("4. A := t1");
		strings.add("5. t2 > 2 3");
		strings.add("6. #12 jif");
		strings.add("7. t1 FALSE");
		strings.add("8. A := t1");
		strings.add("9. t1 + 2 3");
		strings.add("10. B := t1");
		strings.add("11. #5 jmp");
		strings.add("12. #1 jmp");

		as1.comando();

		assertEquals(strings, geradorDeCodigo.getCodigos());
	}

	public void testWhile4() throws UnknownException {
		as1 = new AnalisadorSintatico("WHILE (TRUE) DO BEGIN " + "A := TRUE; "
				+ "IF ( 2 > 1 ) THEN BEGIN B := 2; END ELSE BEGIN B := 3; END; " + "END",
				palavrasReservadas);

		addAtributo(as1, "A", Tipo.T_BOOLEANO);
		addAtributo(as1, "B", Tipo.T_INTEIRO);
		List<String> strings = new LinkedList<String>();
		strings.add("1. t1 TRUE");
		strings.add("2. #13 jif");
		strings.add("3. t1 TRUE");
		strings.add("4. A := t1");
		strings.add("5. t2 > 2 1");
		strings.add("6. #10 jif");
		strings.add("7. t1 2");
		strings.add("8. B := t1");
		strings.add("9. #12 jmp");
		strings.add("10. t1 3");
		strings.add("11. B := t1");
		strings.add("12. #1 jmp");

		as1.comando();

		assertEquals(strings, geradorDeCodigo.getCodigos());
	}

	// </Testes do WHILE>

	// <Testes de Label>

	public void testLABEL1() throws UnknownException {

		as1 = new AnalisadorSintatico("IF ( L1 > jif) THEN BEGIN END", palavrasReservadas);
		addAtributo(as1, "L1", Tipo.T_INTEIRO);
		addAtributo(as1, "jif", Tipo.T_INTEIRO);

		as1.comando();

		List<String> codigosEsperado = new LinkedList<String>();
		codigosEsperado.add("1. t1 > L1 jif");
		codigosEsperado.add("2. #4 jif");
		codigosEsperado.add("3. #4 jmp");
		List<String> codigosRecebido = GeradorDeCodigo.getInstance().getCodigos();

		assertEquals(codigosEsperado, codigosRecebido);
	}

	public void testLABEL2() throws UnknownException {

		as1 = new AnalisadorSintatico("IF ( L1 > jmp) THEN BEGIN END", palavrasReservadas);
		addAtributo(as1, "L1", Tipo.T_INTEIRO);
		addAtributo(as1, "jmp", Tipo.T_INTEIRO);

		as1.comando();

		List<String> codigosEsperado = new LinkedList<String>();
		codigosEsperado.add("1. t1 > L1 jmp");
		codigosEsperado.add("2. #4 jif");
		codigosEsperado.add("3. #4 jmp");
		List<String> codigosRecebido = GeradorDeCodigo.getInstance().getCodigos();

		assertEquals(codigosEsperado, codigosRecebido);
	}

	// </Testes de Label>

	// <Testes de ARRAY>
	public void testARRAYAtribuicao()throws UnknownException {
		
		as1 = new AnalisadorSintatico("meuArray[1 + 1] := 1", palavrasReservadas);
		addAtributo(as1, "meuArray", Tipo.T_INTEIRO, true);
		
		assertTrue(as1.comando());
		
	}
	
	public void testARRAYAtribuicaoErrada1() throws UnknownException {

		AnalisadorSemanticoUnknownRuntimeException exp = null;
		
		as1 = new AnalisadorSintatico("meuArray := 1", palavrasReservadas);
		addAtributo(as1, "meuArray", Tipo.T_INTEIRO, true);
		exp = new AnalisadorSemanticoUnknownRuntimeException("Erro! Ausência do índice de acesso do array");

		try {
			as1.comando();
			fail("Erro! Era pra ter sido lançada uma exceção de erro semântico");
		} catch (UnknownRuntimeException e) {
			assertEquals(exp, e);
		}

	}
	
	// </Testes de ARRAY>
}